﻿using RotovapPlatform.Domain.Business.Recipes.Entities;
using RotovapPlatform.Domain.Business.Storage.Entities;
using RotovapPlatform.Domain.Common;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using RotovapPlatform.Domain.Business.Machine.Enums;
using static RotovapPlatform.Domain.Business.Machine.Enums.ExperimentConfigEnums;

namespace RotovapPlatform.Domain.Services.Scheduling
{
	/// <summary>
	/// 实验变更事件参数
	/// </summary>
	public class CurrentExperimentChangedEventArgs : EventArgs
	{
		/// <summary>
		/// 当前实验
		/// </summary>
		public Experiment CurrentExperiment { get; }

		public CurrentExperimentChangedEventArgs(Experiment currentExperiment)
		{
			CurrentExperiment = currentExperiment;
		}
	}

	/// <summary>
	/// 实验组变更事件参数
	/// </summary>
	public class CurrentExperimentGroupChangedEventArgs : EventArgs
	{
		/// <summary>
		/// 当前实验组ID（可能为null，表示无当前实验组）
		/// </summary>
		public Guid? ExperimentGroupId { get; }

		/// <summary>
		/// 构造函数
		/// </summary>
		/// <param name="experimentGroupId">实验组ID</param>
		public CurrentExperimentGroupChangedEventArgs(Guid? experimentGroupId)
		{
			ExperimentGroupId = experimentGroupId;
		}
	}

	/// <summary>
	/// 任务调度领域服务接口
	/// </summary>
	public interface ITaskSchedulingDomainService
	{
		/// <summary>
		/// 当前实验变更事件
		/// </summary>
		event EventHandler<CurrentExperimentChangedEventArgs> CurrentExperimentChanged;

		/// <summary>
		/// 当前实验组变更事件
		/// </summary>
		event EventHandler<CurrentExperimentGroupChangedEventArgs> CurrentExperimentGroupChanged;

		/// <summary>
		/// 分解实验组为单个实验任务（并保存到数据库）
		/// </summary>
		/// <param name="experimentGroupId">实验组ID</param>
		/// <returns>分解后的实验列表</returns>
		Task<List<Experiment>> DecomposeExperimentGroupDomainAsync(Guid experimentGroupId);

		/// <summary>
		/// 分解实验组为单个实验任务（不保存到数据库，仅用于UI显示）
		/// </summary>
		/// <param name="experimentGroupId">实验组ID</param>
		/// <returns>分解后的实验列表</returns>
		Task<List<Experiment>> DecomposeExperimentGroupWithoutSavingAsync(Guid experimentGroupId);

		/// <summary>
		/// 验证实验组配方
		/// </summary>
		/// <param name="experimentGroupId">实验组ID</param>
		/// <returns>验证结果</returns>
		Task<ValidationResult> ValidateExperimentGroupDomainAsync(string experimentGroupId);

		/// <summary>
		/// 设置当前要执行的实验
		/// </summary>
		/// <param name="experiment">要执行的实验</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> SetCurrentExperimentAsync(Experiment experiment);

		/// <summary>
		/// 设置当前要执行的实验和实验组
		/// </summary>
		/// <param name="experiment">要执行的实验</param>
		/// <param name="experimentGroup">实验所属的实验组</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> SetCurrentExperimentAndGroupAsync(Experiment experiment, ExperimentGroup experimentGroup);

		/// <summary>
		/// 启动实验组
		/// </summary>
		/// <param name="experimentGroup">要启动的实验组</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> StartExperimentGroupDomainAsync(ExperimentGroup experimentGroup);

		/// <summary>
		/// 获取当前正在执行的实验
		/// </summary>
		/// <returns>当前实验，若无则返回null</returns>
		Task<Experiment> GetCurrentExperimentAsync();

		/// <summary>
		/// 获取当前正在执行的实验组
		/// </summary>
		/// <returns>当前实验组，若无则返回null</returns>
		Task<ExperimentGroup> GetCurrentExperimentGroupAsync();

		/// <summary>
		/// 获取当前活动的实验组ID
		/// </summary>
		/// <returns>当前实验组ID，如果没有活动的实验组则返回null</returns>
		Task<Guid?> GetCurrentExperimentGroupIdAsync();

		/// <summary>
		/// 设置当前活动的实验组
		/// </summary>
		/// <param name="experimentGroupId">实验组ID，如果为null则表示清除当前实验组</param>
		/// <returns>操作任务</returns>
		Task SetCurrentExperimentGroupAsync(Guid? experimentGroupId);

		/// <summary>
		/// 根据实验ID获取实验对象
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <returns>实验对象，如果未找到则返回null</returns>
		Task<Experiment> GetExperimentByIdAsync(Guid experimentId);


	}
}